1. /* scfcasin.cpp by K.Tsuru */
  2. // function ID = 9116 since ver 2.18
  3. /*****************************************
  4. SComplex class
  5. It returns arcsin(z).
  6. 1) Casin(z) = -i * Clog{i * z + Csqrt(1 - z * z)}.
  7. 2) Let z = x [+|-] i*y
  8. arcsin(z) = arcsin(x [+|-] i*y) ([+|-]y >= 0)
  9. = arcsin[ (1/2){sqrt( (1+x)^2 + y^2 ) - sqrt( (1-x)^2 + y^2 )} ]
  10. [-|+]i*arccosh[ (1/2){sqrt( (1+x)^2 + y^2 ) + sqrt( (1-x)^2 + y^2 )} ] (ref. Iwanami II p.224)
  11. = arcsin {(|1+z|-|1-z|)/2} [-|+] i*arccosh {(|1+z|+|1-z|)/2}
  12. When y = 0 i.e. z = x, let arcsin(x) = p, sin(p) = x then
  13. |x| <= 1.0 must be satisfied.
  14. *****************************************/
  15. #ifndef SN_H
  16. #include "sn.h"
  17. #endif
  18. #define CasinZ1Method 1 // Method 2) slightly faster
  19. SComplex Casin(const SComplex& z){
  20. if(z == 0.0) return SComplex(0.0, 0.0); // arcsin(0) = 0
  21. if(Im(z) == 0.0){ // pure real z = x
  22. if( Dabs(Re(z)) > 1.0) z.Real().SetError(z.Real().DOMAIN_ERR, "Casin(z) with z = x(x > 1.0))", 9116);
  23. return SComplex(Asin(Re(z)), 0.0); // arcsin(x)
  24. }
  25. #if CasinZ1Method // 14.1sec
  26. SComplex zp1(z + 1.0), zm1(z - 1.0);
  27. SDouble azp1, azm1, rp, ip;
  28. azp1 = Cabs(zp1); // |1+z|
  29. azm1 = Cabs(zm1); // |1-z|
  30. rp = DsDiv(azp1 - azm1, 2); // (|1+z|-|1-z|)/2
  31. rp = Asin(rp);
  32. ip = DsDiv(azp1 + azm1, 2); // (|1+z|+|1-z|)/2
  33. ip = Acosh(ip); // ip > 0
  34. if ( z.Imag().Sign(9115) < 0 ) ip.ChangeSign(9115);
  35. return SComplex(rp, ip);
  36. #else // 16.4sec
  37. SComplex p = 1.0 - z * z;
  38. p = I * z + Csqrt(p);
  39. p = MI * Clog(p);
  40. return p;
  41. #endif
  42. }

scfcasin.cpp : last modifiled at 2015/08/16 15:05:21(1,535 bytes)
created at 2017/10/06 15:21:28
The creation time of this html file is 2017/10/06 15:27:08 (Fri Oct 06 15:27:08 2017).